/**
 * 按照固定延迟调度
 * @template T
 * @param task {() => Promise<T>} 需要周期性执行的任务
 * @param terminatingPredicate {(res: T) => boolean} 中断任务谓词
 * @param initialDelay 初始化延迟 单位毫秒
 * @param period 周期 单位毫秒
 * @return {() => void} 停止任务
 */
export function scheduleWithFixedDelay<R>(
        task: () => Promise<R>,
        terminatingPredicate: (res: R) => boolean,
        initialDelay: number,
        period: number,
): Function {
    let timer: any

    const handler = () => {
        task()
                .then(res => {
                    const terminating = terminatingPredicate(res)
                    if (terminating) {
                        return
                    }
                    timer = window.setTimeout(handler, period)
                })
                .catch(err => {
                    console.error('scheduleWithFixedDelay error', err)
                    timer = window.setTimeout(handler, period)
                })
    }

    timer = window.setTimeout(handler, initialDelay)

    return () => {
        if (timer) {
            window.clearTimeout(timer)
        }
    }
}

/**
 * 按照固定频率调度
 *
 * 如非必须, 应优先使用 {@link scheduleWithFixedDelay}
 * @param task 需要周期执行的任务
 * @param rate 速率
 */
export function scheduleAtFixedRate(task: () => any, rate: number): Function {
    const interval = window.setInterval(task, rate)
    return () => window.clearInterval(interval)
}
